package com.itheima.ydd.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.ydd.common.*;
import com.itheima.ydd.dto.ArticleDto;
import com.itheima.ydd.dto.YddArticleDto;
import com.itheima.ydd.entity.YddArticle;
import com.itheima.ydd.entity.YddCate;
import com.itheima.ydd.entity.YddUser;
import com.itheima.ydd.service.IYddArticleService;
import com.itheima.ydd.service.IYddCateService;
import com.itheima.ydd.service.IYddUserService;

import com.itheima.ydd.common.BusinessException;
import com.itheima.ydd.common.ResultData;
import com.itheima.ydd.entity.*;
import com.itheima.ydd.service.*;
import com.itheima.ydd.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ZhuHongKai
 * @version 1.0
 * @ClassName FrontIndexController
 * @date 2022/10/13 15:20
 */

@RestController
@RequestMapping("/index")
@Slf4j
public class FrontIndexController {

    @Autowired
    private IYddArticleService yddArticleService;
    @Autowired
    private IYddUserService yddUserService;

    @Autowired
    private IYddCateService yddCateService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IYddTagService yddTagService;

    @Autowired
    private IYddLinkService yddLinkService;

    @Autowired
    private IYddAdvimgService yddAdvimgService;

    /**
     * 热门置顶文章数据
     * @param page
     * @param limit
     * @return
     */
    @GetMapping("/new")
    public ResultData newData(int page, int limit){
        // 创建一个返回数据的集合
        Map<String, Object> data = new HashMap<>();
        data.put("desc","首页大列表");

        // 现在的时间
        Date now = new Date();
        // 一周前的时间
        Date weekDate = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7);
        // 一天前的时间
        Date dayDate = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);

        // 获取一周内新的文章数
        LambdaQueryWrapper<YddArticle> wrapper = new LambdaQueryWrapper<>();
        // YddArticle::getCreateDate在weekDate和now之间满足条件，
        wrapper.between(YddArticle::getCreateDate, weekDate, now);
        // YddArticle::getStatus等于2的满足条件
        wrapper.eq(YddArticle::getStatus, 2);
        //调用IYddArticleService中Count统计满足条件数量
        int numWeek = yddArticleService.count(wrapper);
        // 把查询出来的文章数量封装到data集合中
        data.put("num_week", numWeek);

        // 获取一天内新的文章数
        LambdaQueryWrapper<YddArticle> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.between(YddArticle::getCreateDate, dayDate, now);
        wrapper1.eq(YddArticle::getStatus, 2);
        int dayNumWeek = yddArticleService.count(wrapper1);
        data.put("num_day", dayNumWeek);

        // 获取置顶文章
        // 创建分页对象
        Page<YddArticle> pageInfo = new Page<>(page,limit);
        LambdaQueryWrapper<YddArticle> wrapper3 = new LambdaQueryWrapper<>();
        // 根据创建时间进行降序
        wrapper3.orderByDesc(YddArticle::getCreateDate);
        // 查询YddArticle::getIstop等于1
        wrapper3.eq(YddArticle::getIstop, 1);
        // 查询YddArticle::getStatus等于2
        wrapper3.eq(YddArticle::getStatus, 2);
        // 调用yddArticleService中的page方法
        yddArticleService.page(pageInfo, wrapper3);
        // 取出pageInfo中的数据
        List<YddArticle> records = pageInfo.getRecords();

        // 创建第二个page对象
        Page<YddArticleDto> articleDtoPage = new Page<>();
        // 将pageInfo拷贝到articleDtoPage中，records不拷贝进去
        BeanUtils.copyProperties(pageInfo, articleDtoPage, "records");
        List<YddArticleDto> yddArticleDtos = records.stream().map(item -> {
            // 创建YddAdvposDto对象
            YddArticleDto yddArticleDto = new YddArticleDto();
            // 将records中的每个元素拷贝到yddAdvposDto对象中
            BeanUtils.copyProperties(item, yddArticleDto);
            LambdaQueryWrapper<YddCate> wrapper4 = new LambdaQueryWrapper<>();
            // YddCate::getId等于item.getCateid()的满足条件
            wrapper4.eq(YddCate::getId, item.getCateid());
            // 调用cateService中的getOne方法，返回一个对象
            YddCate yddCate = yddCateService.getOne(wrapper4);
            // 判断yddCate是否为null，不为null
            if (yddCate != null) {
                // 不为null修改Catename属性
                yddArticleDto.setCatename(yddCate.getCatename());
            }
            return yddArticleDto;
        }).collect(Collectors.toList());
        // 将数据封装为pageResult
        PageResult pageResult = PageResult.getResultByDtoPage(pageInfo, yddArticleDtos);
        // 将封装好的pageResult作为value，list作为key添加到data里
        data.put("list", pageResult);

        return ResultData.ok2(data);
    }

    /**
     * 最新文章接口
     * @return
     */
    @GetMapping("/hot")
    public ResultData hot(){
        LambdaQueryWrapper<YddArticle> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(YddArticle::getIshot,1).gt(YddArticle::getLovenum,8500).orderByDesc(YddArticle::getLovenum).last("limit 4");

        List<ArticleDto> articleDtos = getArticleDtoList(queryWrapper);

        HashMap<String, Object> ret = new HashMap<>();
        ret.put("desc","侧边最新文章");
        ret.put("list", articleDtos);
        return ResultData.ok("",ret);

    }


    //抽取的方法
    protected List<ArticleDto> getArticleDtoList(LambdaQueryWrapper<YddArticle> queryWrapper){
        return yddArticleService.list(queryWrapper).stream().map((item) -> {
            ArticleDto articleDto = new ArticleDto();
            articleDto.setCatename(yddCateService.getById(item.getCateid()).getCatename());
            articleDto.setId(item.getId().toString());
            articleDto.setTitle(item.getTitle());
            articleDto.setPic(item.getPic());
            articleDto.setLovenum(item.getLovenum());
            return articleDto;
        }).collect(Collectors.toList());
    }

    /**
     * 文章详情
     * @param id
     * @return
     */
    @GetMapping("/show")
    public ResultData show(Integer id){
        // 创建Map对象
        Map<String,Object> data = new HashMap<>();
        //获取前一篇文章title
        List<Map<String, Object>> prev = new ArrayList<>();
        YddArticle prevArticle = null;
        // 每次接收的id-1
        int i = id - 1;
        // 如果prevArticle等于null并且i还大于0进入循环
        while (prevArticle == null && i > 0){
            prevArticle = yddArticleService.getById(i);
            i--;
        }
        Map<String,Object> prevMap = new HashMap<>();

        if (prevArticle != null){
            prevMap.put("id", i + 1);
            prevMap.put("title",prevArticle.getTitle());
            prev.add(prevMap);
        }
        data.put("prev",prev);
        // 获取最后一篇文章title
        List<Map<String,Object>> next = new ArrayList<>();
        YddArticle nextArticle = null;
        int j = id + 1;
        while (nextArticle == null && j > 0){
            nextArticle = yddArticleService.getById(i);
            j++;
        }
        Map<String,Object> nextMap = new HashMap<>(2);
        if (nextMap != null){
            nextMap.put("id",j - 1);
            nextMap.put("title",nextArticle.getTitle());
            next.add(nextMap);
        }
        data.put("next",next);

        // 获取推荐文章
        Page<YddArticle> pageInfo = new Page<>(0,4);
        LambdaQueryWrapper<YddArticle> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(YddArticle::getId);
        queryWrapper.eq(YddArticle::getIshot,1);
        queryWrapper.eq(YddArticle::getStatus,2);
        yddArticleService.page(pageInfo,queryWrapper);
        List<YddArticle> records = pageInfo.getRecords();

        List<Map<String, Object>> recommend  = records.stream().map(item -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", item.getId());
            map.put("tilte", item.getTitle());
            map.put("pic", item.getPic());
            map.put("cateid", item.getCateid());

            LambdaQueryWrapper<YddCate> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(YddCate::getId, item.getId());
            YddCate yddCate = yddCateService.getOne(queryWrapper1);
            if (yddCate != null) {
                map.put("catename", yddCate.getCatename());
            }
            return map;
        }).collect(Collectors.toList());
        data.put("recommend ",recommend);

        // 获取info
        YddArticle article = yddArticleService.getById(id);
        LambdaQueryWrapper<YddCate> queryWrapper1 = new LambdaQueryWrapper<>();
        queryWrapper1.eq(YddCate::getId,article.getCateid());
        YddCate yddCate  = yddCateService.getOne(queryWrapper1);
        YddArticleDto yddArticleDto = new YddArticleDto();
        BeanUtils.copyProperties(article,yddArticleDto);
        yddArticleDto.setCatename(yddCate.getCatename());

        data.put("info",yddArticleDto);
        return ResultData.ok2(data);
    }

    /**
     * 用户注册
     * @param yddUser
     * @return
     */
    @PostMapping("/reg")
    public ResultData register(@RequestBody YddUser yddUser) {
        LambdaQueryWrapper<YddUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YddUser::getMobile, yddUser.getMobile());
        int count = yddUserService.count(queryWrapper);
        //大于0表示手机号已存在
        if (count > 0) {
            throw new BusinessException("该手机号已存在!");
        }
        //对用户输入的密码进行md5加密
        String password = DigestUtils.md5DigestAsHex(yddUser.getPassword().getBytes());
        yddUser.setPassword(password);
        //初始用户名为手机号
        yddUser.setUsername(yddUser.getMobile());
        //注册的用户信息存入数据库
        yddUserService.save(yddUser);
        //生成token
        Map tokenMap = new HashMap<>();
        //将用户id加入到token中
        tokenMap.put("id",yddUser.getId());
        String token = JwtUtils.getToken(tokenMap);
        Map tokenMap2=new HashMap<>();
        tokenMap2.put("token",token);
        return ResultData.ok("注册成功",tokenMap2);
    }

    /**
     * 列表接口
     * @param page
     * @param limit
     * @param cateid
     * @return
     */
    @GetMapping("/list")
    public ResultData page(int page, int limit, Integer cateid){
        Page<YddArticle> pageInfo=new Page<>(page,limit);
        LambdaQueryWrapper<YddArticle>lqw=new LambdaQueryWrapper<>();
//        lqw.eq(StringUtils.isNotEmpty(cateid))
        //根据ID排序徐
        lqw.orderByDesc(YddArticle::getId);
        //如果有条件查询cateid根据id查询
        lqw.eq(cateid!=null,YddArticle::getCateid,cateid);
        yddArticleService.page(pageInfo,lqw);
        List<YddArticleDto> records = pageInfo.getRecords().stream().map(item -> {
           YddArticleDto yddArticleDto=new YddArticleDto();
           yddArticleDto.setId(item.getId());
           yddArticleDto.setTitle(item.getTitle());
           yddArticleDto.setAuthor(item.getAuthor());
           yddArticleDto.setKeywords(item.getKeywords());
           yddArticleDto.setDescription(item.getDescription());
           yddArticleDto.setContent(item.getContent());
           yddArticleDto.setTags(item.getTags());
           yddArticleDto.setIstop(item.getIstop());
           yddArticleDto.setIshot(item.getIshot());
           yddArticleDto.setUserId(item.getUserId());
           yddArticleDto.setCreateDate(item.getCreateDate());
           yddArticleDto.setUpdateDate(item.getUpdateDate());
           yddArticleDto.setClick(item.getClick());
           yddArticleDto.setStatus(item.getStatus());
           yddArticleDto.setCateid(item.getCateid());
           yddArticleDto.setPic(item.getPic());
           yddArticleDto.setLovenum(item.getLovenum());
            LambdaQueryWrapper<YddCate>lambdaQueryWrapper=new LambdaQueryWrapper<>();
            lambdaQueryWrapper.eq(YddCate::getId,item.getCateid());
            YddCate yddCate = yddCateService.getOne(lambdaQueryWrapper);
            yddArticleDto.setCatename(yddCate.getCatename());
            return yddArticleDto;
        }).collect(Collectors.toList());

        PageBean<YddArticleDto> pageBean=new PageBean<>();
        pageBean.setData(records);//封装的具体集合数据
        pageBean.setPageSize(pageInfo.getSize());//每页条数
        pageBean.setCount(pageInfo.getTotal());//总条数
        pageBean.setTotalPages(pageInfo.getPages());//总页数
        pageBean.setCurrentPage(pageInfo.getCurrent());//当前页
       Map<String,Object>map=new HashMap();
       map.put("list",pageBean);

        return ResultData.ok("",map);
    }

    /**
     * 首页和全局数据
     *
     * @return
     */
    @GetMapping("/index")
    public ResultData index() {
        /**
         * 返回前端数据分析
         * 返回数据类型: allCate,config,allTag,allLink,banner,sideBanner,showBanner (广告图数据)
         * 分别为: 所有的文章分类数据,按层级划分的系统配置信息,所有的标签数据,所有的标签数据,
         * 以上述字段为key值创建map集合封装数据
         */
        //定义map集合返回所有数据
        Map<String, Object> data = new HashMap<>();

        //allCate,查询出文章分类数据
        List<YddCate> yddCates = yddCateService.list();
        data.put("allCate", yddCates);

        //config,存放系统配置信息
        Map<String, Object> config = new HashMap<>();
        //config下有allDate,list两个子数据集,分别定义list集合
        //设置list,list下有多级数据,定义getList()方法获取数据
        List<Map<String, Object>> list = sysConfigService.getList();
        //设置alldata,查出文章分类数据
        List<SysConfig> allData = sysConfigService.list();

        config.put("list", list);
        config.put("allData", allData);

        data.put("config", config);

        //allTag,标签
        List<YddTag> yddTags = yddTagService.list();
        data.put("allTag", yddTags);

        //allLink,友情链接
        List<YddLink> yddLinks = yddLinkService.list();
        data.put("allLink", yddLinks);
         //广告图
        //banner
        LambdaQueryWrapper<YddAdvimg> wrapper = new LambdaQueryWrapper<>();
        //广告为id 15,系统默认四个
        wrapper.eq(YddAdvimg::getAdvimgpos, 15);
        List<YddAdvimg> yddAdvimgs = yddAdvimgService.list(wrapper);
        data.put("banner", yddAdvimgs);

        //sideBanner
        LambdaQueryWrapper<YddAdvimg> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(YddAdvimg::getAdvimgpos, 14);
        List<YddAdvimg> yddAdvimgsSide = yddAdvimgService.list(wrapper2);
        data.put("sideBanner", yddAdvimgsSide);

        //showBanner
        LambdaQueryWrapper<YddAdvimg> wrapper3 = new LambdaQueryWrapper<>();
        wrapper3.ne(YddAdvimg::getAdvimgpos, 12);
        wrapper3.ne(YddAdvimg::getAdvimgpos, 13);

        List<YddAdvimg> yddAdvimgsShow = yddAdvimgService.list(wrapper3);
        data.put("showBanner", yddAdvimgsShow);

        return ResultData.ok("",data);
    }

    /**
     * 首页侧边推荐文章
     *
     * @return
     */
    @GetMapping("/recommend")
    public ResultData recommend() {

        Map<String, Object> data = new HashMap<>();
        data.put("desc", "侧边推荐文章");

        //获取推荐文章
        //条件构造
        LambdaQueryWrapper<YddArticle> wrapper = new LambdaQueryWrapper<>();
        //分页查询条件，根据id查询
        wrapper.orderByDesc(YddArticle::getId);
        //Ishot(1是推荐)为1的和Status(状态)为2的都是
        wrapper.eq(YddArticle::getIshot, 1);
        wrapper.eq(YddArticle::getStatus, 2);
        List<YddArticle> yddArticles = yddArticleService.list(wrapper);

        List<YddArticle> newArticles = new ArrayList<>();
       //选出6
        for (int i = 0; i < 6; i++) {
            newArticles.add(yddArticles.get(i));
        }
        List<YddArticleDto> yddArticleDtos = newArticles.stream().map(item -> {
            YddArticleDto yddArticleDto = new YddArticleDto();
            //对象拷贝
            BeanUtils.copyProperties(item, yddArticleDto);
            LambdaQueryWrapper<YddCate> wrapper1 = new LambdaQueryWrapper<>();
            //设置文章分类条件
            wrapper1.eq(YddCate::getId, item.getCateid());
            //查询每个分类下文章数据
            YddCate yddCate = yddCateService.getOne(wrapper1);
            if (yddCate != null) {
                //分类名存入YddArticleDto的catename字段
                yddArticleDto.setCatename(yddCate.getCatename());
            }
            return yddArticleDto;
        }).collect(Collectors.toList());

        data.put("list", yddArticleDtos);

        return ResultData.ok("",data);


    }
}
